package com.yanboo.modules.quartz.task;

import com.yanboo.constant.ProcessorMsgType;
import com.yanboo.constant.ProcessorStatus;
import com.yanboo.modules.mnt.service.ProcessorService;
import com.yanboo.modules.mnt.service.dto.ProcessorDto;
import com.yanboo.modules.mnt.service.dto.ProcessorQueryCriteria;
import com.yanboo.modules.mnt.websocket.processor.StatusWSService;
import com.yanboo.modules.mnt.websocket.processor.dto.ProcessorStatusDto;
import com.yanboo.modules.mnt.websocket.processor.dto.ProcessorWSMsgDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Slf4j
@Service
public class ProcessorCheckTask implements ApplicationRunner {

    @Autowired
    ProcessorService processorService;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        List<ProcessorDto> processorDtos = processorService.queryAll(new ProcessorQueryCriteria());
        for (ProcessorDto processorDto : processorDtos) {
            if (processorDto.getPid()==null){
                continue;
            }
            Optional<ProcessHandle> processHandle = ProcessHandle.of(processorDto.getPid());
            if (processHandle.isPresent() && processHandle.get().isAlive() && !processorDto.getStatus().equals(ProcessorStatus.RUNNING)){
                processorService.update(processorDto.setStatus(ProcessorStatus.RUNNING));
            }
            if (processHandle.isPresent() && !processHandle.get().isAlive() && processorDto.getStatus().equals(ProcessorStatus.RUNNING)){
                processorService.update(processorDto.setStatus(ProcessorStatus.EXIT));
            }

            //TODO 根据可执行文件路径判断进程是否存在。
        }
    }

    @Scheduled(cron = "0/5 * * * * ?")
    public void run() {
        List<ProcessorDto> processorDtos = processorService.queryAll(new ProcessorQueryCriteria());
        processorDtos.forEach(processorDto -> {
            ProcessHandle processHandle = ProcessHandle.of(processorDto.getPid()).orElse(null);
            if (processHandle == null || !processHandle.isAlive()) {
                processorService.update(processorDto.setStatus(ProcessorStatus.ERROR).setPid(null));
                return;
            }
            if (processHandle.isAlive() && processorDto.getStatus() != ProcessorStatus.RUNNING) {
                processorService.update(processorDto.setStatus(ProcessorStatus.RUNNING));
            }
            StatusWSService.sendMsg(processorDto.getId(), new ProcessorWSMsgDto().setType(ProcessorMsgType.STATUS)
                    .setMsg(new ProcessorStatusDto()
                            .setId(String.valueOf(processorDto.getId()))
                            .setStatus(processHandle.isAlive()?ProcessorStatus.RUNNING:ProcessorStatus.ERROR)
                            .setPid(String.valueOf(processorDto.getPid()))));
        });
    }
}
